package leetcode.code1006;

import leetcode.IDebug;
import leetcode.helper.H;

public class Solution implements IDebug {

	public boolean parseBoolExpr(String expression) {
		if (expression.equals("t")) {
			return true;
		}
		if (expression.equals("f")) {
			return false;
		}
		char c = expression.charAt(0);
		expression = expression.substring(2, expression.length() - 1);
		if (c == '!') {
			return !this.parseBoolExpr(expression);
		}
		if (c == '&') {
			return and(expression);
		}
		return or(expression);// c == '|'
	}

	private boolean or(String expression) {
		return this.op(expression, false, (a, b) -> a | this.parseBoolExpr(b));
	}

	private boolean and(String expression) {
		return this.op(expression, true, (a, b) -> a & this.parseBoolExpr(b));
	}

	interface ILogic {
		boolean op(boolean ans, String exp);
	}

	private boolean op(String expression, boolean init, ILogic logic) {
		boolean ans = init;
		StringBuffer sb = new StringBuffer();
		int cnt = 0;
		for (char c : expression.toCharArray()) {
			if (c == ',' && cnt == 0) {
				ans = logic.op(ans, sb.toString());
				sb = new StringBuffer();
			} else {
				if (c == '(') {
					cnt++;
				} else if (c == ')') {
					cnt--;
				}
				sb.append(c);
			}
		}
		return logic.op(ans, sb.toString());
	}

	@Override
	public void debug4() {
		H.compare(false, this.parseBoolExpr("|(&(t,f,t),!(t))"));
		H.compare(false, this.parseBoolExpr("&(t,f)"));
		H.compare(false, this.parseBoolExpr("&(|(f))"));
		H.compare(true, this.parseBoolExpr("!(f)"));

	}

	@Override
	public void debug3() {
		// TODO Auto-generated method stub

	}

	@Override
	public void debug2() {
		// TODO Auto-generated method stub

	}

	@Override
	public void debug1() {
		// TODO Auto-generated method stub

	}

	public static void main(String[] args) {
		Solution so = new Solution();
		so.debug1();
		so.debug2();
		so.debug3();
		so.debug4();
		System.out.println(true | false);
		System.out.println(true & false);
	}

}
